package edu.yctc.weblog.service.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import edu.yctc.weblog.constant.ResultCode;
import edu.yctc.weblog.dao.LinkDAO;
import edu.yctc.weblog.entity.LinkDO;
import edu.yctc.weblog.entity.PageDO;
import edu.yctc.weblog.entity.ResultDO;
import edu.yctc.weblog.service.LinkService;
import edu.yctc.weblog.utils.PageQueryUtil;

@Service("linkService")
public class LinkServiceImpl implements LinkService {

    private final static Logger LOG = LoggerFactory.getLogger("serviceLogger");

    @Resource
    private LinkDAO linkDAO;

    @Override
    public ResultDO<PageDO> getBlogLinkPage(PageQueryUtil pageQueryUtil) {
        List<LinkDO> linkDOs = linkDAO.getLinkList(pageQueryUtil);
        int total = linkDAO.getTotalLinks();
        PageDO pageDO = new PageDO(total, pageQueryUtil.getLimit(), pageQueryUtil.getPage(), linkDOs);
        LOG.info("get blog link page success, links={}", linkDOs);
        return new ResultDO<PageDO>(true, ResultCode.SUCCESS, ResultCode.MSG_SUCCESS, pageDO);
    }

    @Override
    public ResultDO<Integer> getTotalLinks() {
        LOG.info("get total links success");
        return new ResultDO<Integer>(true, ResultCode.SUCCESS, ResultCode.MSG_SUCCESS, linkDAO.getTotalLinks());
    }

    @Override
    @Transactional
    public ResultDO<Void> saveLink(LinkDO linkDO) {
        linkDAO.insert(linkDO);
        LOG.info("save linkDO success, linkDO={}", linkDO);
        return new ResultDO<>(true, ResultCode.SUCCESS, ResultCode.MSG_SUCCESS);
    }

    @Override
    public ResultDO<LinkDO> getLinkDOById(Long id) {
        if (id <= 0) {
            LOG.error("get linkDO by id fail, parameter invalid, id={}", id);
            return new ResultDO<LinkDO>(false, ResultCode.PARAMETER_INVALID, ResultCode.MSG_PARAMETER_INVALID, null);
        }
        LinkDO linkDO = linkDAO.getLinkDOById(id);
        if (linkDO == null) {
            LOG.error("get linkDO by id fail, no such linkDO, id={}", id);
            return new ResultDO<LinkDO>(false, ResultCode.DB_ERROR, ResultCode.MSG_DB_ERROR, null);
        }
        return new ResultDO<LinkDO>(true, ResultCode.SUCCESS, ResultCode.MSG_SUCCESS, linkDO);
    }

    @Override
    @Transactional
    public ResultDO<Void> updateLink(LinkDO linkDO) {
        linkDAO.update(linkDO);
        LOG.info("update linkDO success, linkDO={}", linkDO);
        return new ResultDO<>(true, ResultCode.SUCCESS, ResultCode.MSG_SUCCESS);
    }

    @Override
    @Transactional
    public ResultDO<Void> deleteBatch(Long[] ids) {
        linkDAO.deleteBatch(ids);
        LOG.info("delete batch success, link ids={}", new ArrayList<>(Arrays.asList(ids)));
        return new ResultDO<>(true, ResultCode.SUCCESS, ResultCode.MSG_SUCCESS);
    }

    @Override
    public ResultDO<Map<Integer, List<LinkDO>>> getLinksForLinkPage() {
        List<LinkDO> linkDOs = linkDAO.getLinkList(null);
        if (linkDOs.size() > 0) {
            // 根据type分组
            Map<Integer, List<LinkDO>> linkDOMap = linkDOs.stream().collect(Collectors.groupingBy(LinkDO::getType));
            LOG.info("get links for link page success, links={}", linkDOMap);
            return new ResultDO<Map<Integer, List<LinkDO>>>(true, ResultCode.SUCCESS, ResultCode.MSG_SUCCESS,
                linkDOMap);
        }
        LOG.error("get links for link page fail, no links");
        return new ResultDO<Map<Integer, List<LinkDO>>>(false, ResultCode.DB_ERROR, ResultCode.MSG_DB_ERROR, null);
    }

}
